package basic;

import java.awt.Point;
import java.util.ArrayList;

/**
 * The Class Entity.
 */
public class Entity {

	/** The list of the attributes. */
	private ArrayList<Attribute> attributes;

	/** The list of the primary keys. */
	private ArrayList<Attribute> pk_attributes;

	/** The draw_h_type. By default everything is visible */
	private boolean draw_h_type = false;

	/** The draw_h_attributes. */
	private boolean draw_h_attributes = false;

	/** The visible. */
	private boolean visible = true;

	/** The name of the entity. */
	private String name = "";

	/** The sql output to write to. */
	private String sql = "";

	/** The x is the value of x-axis in relation of the grid svg. */
	private int x = 0;

	/** The y is the value of y-axis in relation of the grid svg. */
	private int y = 0;

	/** The start coordinate according to the svg grid. */
	private Point start;

	/** The end coordinate according to the svg grid. */
	private Point end;

	private int max_attr_name;
	private int max_attr_type;
	private int max_attr_null;
	private int max_attr_default;

	/**
	 * Instantiates a new entity.
	 */
	public Entity() {
		this.name = "";
		this.attributes = new ArrayList<Attribute>();
		this.pk_attributes = new ArrayList<Attribute>();
		this.start = new Point(0, 0);
		this.end = new Point(0, 0);
		this.max_attr_name = 0;
		this.max_attr_type = 0;
		this.max_attr_null = 0;
		this.max_attr_default = 0;
	}

	/**
	 * Getter methods
	 * 
	 * @return
	 */
	public int getMaxAttrName() {
		return this.max_attr_name;
	}

	public int getMaxAttrType() {
		return this.max_attr_type;
	}

	public int getMaxAttrNull() {
		return this.max_attr_null;
	}

	public int getMaxAttrDefault() {
		return this.max_attr_default;
	}

	/**
	 * Instantiates a new entity, overloaded method.
	 * 
	 * @param name
	 *            the entity name
	 */
	public Entity(String name) {
		this.name = name;
		this.attributes = new ArrayList<Attribute>();
		this.pk_attributes = new ArrayList<Attribute>();
		;
		this.start = new Point(0, 0);
		this.end = new Point(0, 0);
	}

	/**
	 * Gets the entity name.
	 * 
	 * @return the name
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * follows are setter/getter methods for end and start entity coordinates.
	 * 
	 * @return the start point
	 */
	public Point getStartPoint() {
		return this.start;
	}

	/**
	 * Gets the end point.
	 * 
	 * @return the end point
	 */
	public Point getEndPoint() {
		return this.end;
	}

	/**
	 * Sets the end point.
	 * 
	 * @param x
	 *            the x
	 * @param y
	 *            the y
	 */
	public void setEndPoint(int x, int y) {
		this.end.setLocation(x, y);
	}

	/**
	 * Sets the start point.
	 * 
	 * @param x
	 *            the x
	 * @param y
	 *            the y
	 */
	public void setStartPoint(int x, int y) {
		this.start.setLocation(x, y);
	}

	/**
	 * Sets the name.
	 * 
	 * @param name
	 *            the new name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Gets the draw h type.
	 * 
	 * @return the draw h type
	 */
	public boolean getDrawHType() {
		return this.draw_h_type;
	}

	/**
	 * Gets the draw h attributes.
	 * 
	 * @return the draw h attributes
	 */
	public boolean getDrawHAttributes() {
		return this.draw_h_attributes;
	}

	/**
	 * Gets the draw visible.
	 * 
	 * @return the draw visible
	 */
	public boolean getDrawVisible() {
		return this.visible;
	}

	/**
	 * Sets the draw h type.
	 * 
	 * @param bool
	 *            the new draw h type
	 */
	public void setDrawHType(boolean bool) {
		this.draw_h_type = bool;
	}

	/**
	 * Sets the draw h attributes.
	 * 
	 * @param bool
	 *            the new draw h attributes
	 */
	public void setDrawHAttributes(boolean bool) {
		this.draw_h_attributes = bool;
	}

	/**
	 * Sets the draw visible.
	 * 
	 * @param bool
	 *            the new draw visible
	 */
	public void setDrawVisible(boolean bool) {
		this.visible = bool;
	}

	/**
	 * Adds the new attribute into attributes's list.
	 * 
	 * @param name
	 *            the name
	 * @param type
	 *            the type
	 * @param num
	 *            the number of attribute
	 * @param Null
	 *            the null
	 * @param Default
	 *            the default
	 * @param auto
	 *            the auto
	 */
	public void addNewAttr(String name, String type, String num, boolean Null,
			String Default, boolean auto) {
		this.max_attr_name = ((this.max_attr_name == 0 || name.length() > this.max_attr_name) ? name
				.length() : this.max_attr_name);

		String full_type = (num.compareTo("") == 0 ? type : type + "(" + num
				+ ")");
		this.max_attr_type = ((this.max_attr_type == 0 || full_type.length() > this.max_attr_type) ? full_type
				.length() : this.max_attr_type);

		String StrNull = (Null ? "NULL" : "NOT NULL");
		this.max_attr_null = ((this.max_attr_null == 0 || StrNull.length() > this.max_attr_null) ? StrNull
				.length() : this.max_attr_null);

		String StrDefault = (auto ? "autoincrement" : "Default '" + Default
				+ "'");
		this.max_attr_default = ((this.max_attr_default == 0 || StrDefault
				.length() > this.max_attr_default) ? StrDefault.length()
				: this.max_attr_default);

		this.attributes
				.add(new Attribute(name, type, num, Null, Default, auto));
	}

	/**
	 * Sets the attribute default of last attribute.
	 * 
	 * @param Default
	 *            the new attribute default of last attribute
	 */
	public void setAttrDefaultOfLastAttr(String Default) {
		if (this.attributes.size() >= 0)
			this.attributes.get(this.attributes.size() - 1).setDefault(Default);
	}

	/**
	 * Adds the new attribute by reference.
	 * 
	 * @param attr
	 *            the attribute
	 */
	public void addNewAttrByRef(Attribute attr) {
		this.addNewAttr(attr.getName(), attr.getType(), attr.getNum(),
				attr.getNull(), attr.getDefault(), attr.getAutoIncr());
	}

	/**
	 * Adds the attribute string in primary key.
	 * 
	 * @param name
	 *            the attribute's name
	 */
	public void addAttrInPrimaryKey(String name) {
		Attribute att = null;
		att = getAttrFromAttrName(name);
		if (att != null)
			this.pk_attributes.add(att);
	}

	/**
	 * Gets the attribute from attribute's name.
	 * 
	 * @param name
	 *            the attribute name
	 * @return the attribute attribute from the input string with the same name
	 */
	public Attribute getAttrFromAttrName(String name) {
		Attribute att = null;
		for (int i = 0; i < this.attributes.size(); i++) {
			if (this.attributes.get(i).getName().compareTo(name) == 0)
				att = this.attributes.get(i);
		}
		return att;
	}

	/**
	 * Gets the whole list attribute.
	 * 
	 * @return the attributes list
	 */
	public ArrayList<Attribute> getAttr() {
		return this.attributes;
	}

	/**
	 * Gets the whole list pk_attributes.
	 * 
	 * @return the pk_attributes list
	 */
	public ArrayList<Attribute> getPkAttr() {
		return this.pk_attributes;
	}

	/**
	 * Checks if is attribute in primay key.
	 * 
	 * @param name
	 *            the name
	 * @return true, if successful
	 */
	public boolean IsAttrInPk(String name) {
		boolean bool = false;
		for (int i = 0; i < this.pk_attributes.size(); i++) {
			if (this.pk_attributes.get(i).getName().compareTo(name) == 0)
				bool = true;
		}
		return bool;
	}

	/**
	 * Checks if is default in attributes.
	 * 
	 * @return true, if successful
	 */
	public boolean IsDefaultInAttributes() {
		boolean bool = false;
		for (int i = 0; i < this.attributes.size(); i++) {
			if (this.attributes.get(i).getDefault().compareTo("") != 0)
				return true;
		}
		return bool;
	}

	/**
	 * Checks if is auto-increment in primary key.
	 * 
	 * @return true, if successful
	 */
	public boolean IsAutoincrementInPk() {
		boolean bool = false;
		for (int i = 0; i < this.pk_attributes.size(); i++) {
			if (this.pk_attributes.get(i).getAutoIncr() == true)
				return true;
		}
		return bool;
	}

	/**
	 * Gets the sQL table.
	 * 
	 * @return the sQL table
	 */
	public void getSQLTable() {
		String str = "";
		str += "CREATE TABLE " + this.getName() + "(\n";

		for (int i = 0; i < this.attributes.size(); i++)
			str += getSQL4Attr(this.attributes.get(i));

		String c = "";
		for (int j = 0; j < this.pk_attributes.size(); j++) {
			if (j > 0)
				c += ", ";
			c += this.pk_attributes.get(j).getName();
		}
		str += "\t PRIMARY KEY ( " + c + " )";
		this.sql = str;
	}

	/**
	 * Composes the structure of a correct model in sql concerning the insert of
	 * attributes
	 * 
	 * @param attr
	 *            the attribute
	 * @return the sQ l4 attribute
	 */
	public static String getSQL4Attr(Attribute attr) {
		String str = "";

		String campo = "";
		String tipo = "";
		String Null = "";
		String Num = "";
		String Default = "";
		boolean autoinc = false;

		campo = attr.getName();
		tipo = attr.getType();
		Num = attr.getNum();
		autoinc = attr.getAutoIncr();
		Null = (((attr.getDefault().compareTo("") == 0 || attr.getDefault()
				.compareTo("null") == 0) && !autoinc) ? "NULL" : "NOT NULL");
		Default = ((attr.getDefault().compareTo("") == 0 || attr.getDefault()
				.compareTo("null") == 0) ? "" : attr.getDefault());

		str += "\t" + campo + " " + tipo + (Num == "" ? "" : "(" + Num + ")")
				+ " " + Null + (autoinc ? " auto_increment" : "")
				+ (Default == "" ? "" : " DEFAULT '" + Default + "'");
		str += ",\n";

		return str;
	}

	/**
	 * Gets the sql string saved.
	 * 
	 * @return the sql string
	 */
	public String getSQL() {
		return this.sql;
	}

	/**
	 * Returns width of entity box unused.
	 * 
	 * @return the width
	 */
	public int getWidth() {
		if (this.getDrawVisible()) {
			int maxLength = this.name.length();
			if (!this.getDrawHAttributes()) {
				for (int i = 0; i < attributes.size(); i++) {
					Attribute attr = (Attribute) attributes.get(i);
					if (attr.getCompleteSizaAttribute(this.getDrawHType()) > maxLength) {
						maxLength = attr.getCompleteSizaAttribute(this
								.getDrawHType());
					}
				}
			}
			return maxLength;
		}
		return 0;
	}

	/**
	 * Returns height of entity box unused.
	 * 
	 * @return the height
	 */

	public int getHeight() {
		int numItems = 1;

		if (!this.getDrawHAttributes()) {
			numItems += attributes.size();
		}

		return numItems;
	}

	/**
	 * Sets the value on the x-axis to the grid svg.
	 * 
	 * @param x
	 *            the new x
	 */
	public void setX(int x) {
		this.x = x;
	}

	/**
	 * Sets the value on the y-axis to the grid svg.
	 * 
	 * @param y
	 *            the new y
	 */
	public void setY(int y) {
		this.y = y;
	}

	/**
	 * Gets the x.
	 * 
	 * @return the x
	 */
	public int getX() {
		return this.x;
	}

	/**
	 * Gets the y.
	 * 
	 * @return the y
	 */
	public int getY() {
		return this.y;
	}

}
